//
//  WBNetworkManager.swift
//  微博
//
//  Created by 康智桐 on 2018/4/13.
//  Copyright © 2018年 Kk. All rights reserved.
//

import UIKit
import AFNetworking



/**
 - 如果日常开发中，发现网络请求返回的状态码是 405，不支持的网络请求方法
 - 首先应该查找网路请求方法是否正确
 */

enum WBHTTPMethod {
    case GET
    case POST
}

//网络管理工具
class WBNetworkManager: AFHTTPSessionManager {
    
    //静态区/常量(单例)
    //在第一次访问时，执行闭包，并且将结果保存在shared常量中
    
    
    static let shared:WBNetworkManager = {
        
        let instance = WBNetworkManager()
        
        //设置响应反序列化的数据类型
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        
        
        
        return instance
    }()
    
    
    
   lazy var userAccount = WBUserAccount()
    
    
    //用户登录标记
    var userLogon : Bool{
        return userAccount.access_token != nil
    }
    
    //专门负责拼接token的网络请求方法
    func tokenRequest(method:WBHTTPMethod = .GET,URLString :String,parameters:[String:Any],completion:@escaping (_ json:Any?,_ isSuccess:Bool)->()){
        
        
        //处理token字典
        //判断参数字典是否存在
        guard let token = userAccount.access_token else {
        
            print("没有token，需要登录")
            
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: WBUserShouldLoginNotification), object: nil)
            
            completion(nil, false)
            return
        }
        
        
        var parameters = parameters
        if parameters == nil{
            
            parameters = [String:Any]()
        }
        //设置参数字典，此处字典一定有值
        parameters["access_token"] = token
        
        //调用request发起真正的网络请求
        //request(URLString: URLString, parameters: parameters, completion: completion)
        request(method: method, URLString: URLString, parameters: parameters, completion: completion)
        
    }
    
    
    
    /// 上传文件必须是 POST 方法，GET 只能获取数据
    /// 封装 AFN 的上传文件方法
    ///
    /// - parameter URLString:  URLString
    /// - parameter parameters: 参数字典
    /// - parameter name:       接收上传数据的服务器字段(name - 要咨询公司的后台) `pic`
    /// - parameter data:       要上传的二进制数据
    /// - parameter completion: 完成回调
    func upload(URLString: String, parameters: [String: Any]?, name: String, data: Data, completion: @escaping (_ json: Any?, _ isSuccess: Bool)->()){
        
        post(URLString, parameters: parameters, constructingBodyWith: { (formData) in
            
            // 创建 formData
            /**
             1. data: 要上传的二进制数据
             2. name: 服务器接收数据的字段名
             3. fileName: 保存在服务器的文件名，大多数服务器，现在可以乱写
             很多服务器，上传图片完成后，会生成缩略图，中图，大图...
             4. mimeType: 告诉服务器上传文件的类型，如果不想告诉，可以使用 application/octet-stream
             image/png image/jpg image/gif
             */
            formData.appendPart(withFileData: data, name: name, fileName: "xxx", mimeType: "application/octet-stream")
            
            }, progress: nil, success: { (_, json) in
                
                completion(json, true)

                
            }) { (task, error) in
            
                if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                    print("Token 过期了")
                    
                    // 发送通知，提示用户再次登录(本方法不知道被谁调用，谁接收到通知，谁处理！)
                    NotificationCenter.default.post(
                        name: NSNotification.Name(rawValue: WBUserShouldLoginNotification),
                        object: "bad token")
                }
                
                print("网络请求错误 \(error)")
                
                completion(nil, false)
                
        }
    }
    
    
    
    
    
    //使用一个函数封装AFN的get和post请求
    func request(method:WBHTTPMethod = .GET,URLString :String,parameters:[String:Any],completion:@escaping (_ json:Any?,_ isSuccess:Bool)->()){
        
        //成功回调
        let success = { (task:URLSessionDataTask,json :Any)->() in
            
            completion(json,true)
        }
        //失败回调
        let failure = { (task:URLSessionDataTask?, error:Error)->() in
            
            
            //针对403处理用户token过期
            if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                print("Token 过期了")
                
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: WBUserShouldLoginNotification), object: "bad token")
            }
            
            
            print("网络请求错误\(error)")
            completion(nil, false)
        }
        if method == .GET {
            
            get(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
            
        }else{
            
            post(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
            
        }
    }
}
